﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using Wallpaper.Class;

namespace Wallpaper.Partial
{
    public class ItemUnit : ItemUnitBased
    {
        /// <summary>
        /// 视频封面图
        /// </summary>
        public ImageSource image { get; set; } = Static.Image_Error;

        /// <summary>
        /// 动画
        /// </summary>
        public DoubleAnimation animation = new DoubleAnimation();

        private const int ScaleAnimationTime = 200; // 动画总时长
        private double StartActualWidth = 0;
        private double ScaleMinWidth = 0;
        private double ScaleMaxWidth = 0;
        private const double ScaleMultiple = 1.25;

        public ItemUnit(ItemUnitBased based)
        {
            this.VideoTitle = based.VideoTitle;
            this.VideoPath = based.VideoPath;
            try
            {
                if(based.ImagePath != null)
                {
                    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(based.ImagePath);
                    image = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                        bitmap.GetHbitmap(),
                        IntPtr.Zero,
                        Int32Rect.Empty,
                        BitmapSizeOptions.FromEmptyOptions());
                    bitmap.Dispose();
                }
            }
            catch (Exception e)
            {
                Dialog.ShowDialog_Exception(e);
            }
        }

        /// <summary>
        /// 开始播放放大动画
        /// </summary>
        public void StartScaleUpAnimation(Image sender)
        {
            if(StartActualWidth == 0)
            {
                StartActualWidth = sender.ActualWidth;
                ScaleMinWidth = StartActualWidth;
                ScaleMaxWidth = StartActualWidth * ScaleMultiple;
            }
            animation.BeginTime = null;
            animation.From = sender.ActualWidth;
            animation.To = ScaleMaxWidth;
            animation.Duration = TimeSpan.FromMilliseconds(ScaleAnimationTime * (ScaleMaxWidth - sender.ActualWidth) / (ScaleMaxWidth - ScaleMinWidth));
            animation.BeginTime = TimeSpan.Zero;
            sender.BeginAnimation(FrameworkElement.WidthProperty, animation);
        }

        /// <summary>
        /// 开始播放缩小动画
        /// </summary>
        public void StartScaleDownAnimation(Image sender)
        {
            animation.BeginTime = null;
            animation.From = sender.ActualWidth;
            animation.To = ScaleMinWidth;
            animation.Duration = TimeSpan.FromMilliseconds(ScaleAnimationTime * (sender.ActualWidth - ScaleMinWidth) / (ScaleMaxWidth - ScaleMinWidth));
            animation.BeginTime = TimeSpan.Zero;
            sender.BeginAnimation(FrameworkElement.WidthProperty, animation);
        }

        public override bool Equals(object obj)
        {
            if(obj is ItemUnit unit)
            {
                return unit.VideoPath == this.VideoPath;
            }
            else
            {
                return false;
            }
        }
    }

    [Serializable]
    public class ItemUnitBased
    {
        /// <summary>
        /// 视频标题
        /// </summary>
        public string VideoTitle { get; set; }

        /// <summary>
        /// 视频路径
        /// </summary>
        public string VideoPath { get; set; }

        /// <summary>
        /// 封面图路径
        /// </summary>
        public string ImagePath { get; set; }

        public static ItemUnitBased ReadFromFile(string file)
        {
            FileStream fileStream = null;
            try
            {
                fileStream = new FileStream(file, FileMode.Open);
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                ItemUnitBased unit = (ItemUnitBased)binaryFormatter.Deserialize(fileStream);
                return unit;
            }
            finally
            {
                fileStream?.Dispose();
            }
        }

        public void WriteToFile(string file)
        {
            FileStream fileStream = null;
            try
            {
                fileStream = new FileStream(file, FileMode.Create);
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(fileStream, this);
            }
            finally
            {
                fileStream?.Dispose();
            }
        }
    }
}
